#include "memory.h"

static s_segment GDT[3];

void init_gdt ()
{
  s_gdtr gdtr;

  /* NULL segment */
  GDT[0].base_adress = 0;
  GDT[0].segment_limit = 0;
  GDT[0].base_low = 0;
  GDT[0].flag1 = 0;
  GDT[0].flag2 = 0;
  GDT[0].base_high = 0;

  /* code segment */
  GDT[1].base_adress = 0;
  GDT[1].segment_limit = 0xffff;
  GDT[1].base_low = 0;
  GDT[1].flag1 = 0x9a;
  GDT[1].flag2 = 0xdf;
  GDT[1].base_high = 0;

  /* data segment */
  GDT[2].base_adress = 0;
  GDT[2].segment_limit = 0xffff;
  GDT[2].base_low = 0;
  GDT[2].flag1 = 0x92;
  GDT[2].flag2 = 0xdf;
  GDT[2].base_high = 0;

  gdtr.lim = 3 * (sizeof (s_segment)) - 1;
  gdtr.gdt = (unsigned int) &GDT;

  __asm__ ("lgdt %0"
	   :
	   : "m" (gdtr)
	   :);


  __asm__ ("movl %cr0, %eax\n\t"
	   "or   $0x1, %eax\n\t"
	   "movl %eax, %cr0\n\t"
	   "movw $0x10, %ax\n\t"
	   "movw %ax, %ds\n\t"
	   "movw %ax, %ss\n\t"
	   "push $0x08\n\t"
	   "push $1f\n\t"
	   "lret\n\t"
	   "1:\n\t");

}
